package com.nd.fastdp.sys.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nd.fastdp.file.service.FileService;
import com.nd.fastdp.framework.pojo.constant.DelStatusEnum;
import com.nd.fastdp.framework.pojo.constant.StatusEnum;
import com.nd.fastdp.framework.pojo.dto.DelParam;
import com.nd.fastdp.org.model.bo.org.DeptBO;
import com.nd.fastdp.org.model.bo.user.UserBO;
import com.nd.fastdp.org.model.dto.user.UserListParam;
import com.nd.fastdp.org.service.DeptService;
import com.nd.fastdp.org.service.UserService;
import com.nd.fastdp.sys.constant.MsgStateEnum;
import com.nd.fastdp.sys.constant.NoticeReceiverTypeEnum;
import com.nd.fastdp.sys.constant.NoticeStateEnum;
import com.nd.fastdp.sys.convert.NoticeConvert;
import com.nd.fastdp.sys.dao.NoticeMapper;
import com.nd.fastdp.sys.dao.NoticeReceiverMapper;
import com.nd.fastdp.sys.dao.NoticeReceiverVMapper;
import com.nd.fastdp.sys.model.bo.notice.NoticeBO;
import com.nd.fastdp.sys.model.bo.notice.NoticeReceiverBO;
import com.nd.fastdp.sys.model.bo.notice.NoticeReceiverVBO;
import com.nd.fastdp.sys.model.dto.notice.*;
import com.nd.fastdp.sys.model.entity.Notice;
import com.nd.fastdp.sys.model.entity.NoticeReceiver;
import com.nd.fastdp.sys.model.view.NoticeReceiverV;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
public class NoticeServiceImpl implements NoticeService {

    @Autowired
    private NoticeMapper noticeMapper;

    @Autowired
    private NoticeReceiverMapper noticeReceiverMapper;

    @Autowired
    private NoticeReceiverVMapper noticeReceiverVMapper;

    @Autowired
    private FileService fileService;

    @Autowired
    private UserService userService;

    @Autowired
    private DeptService deptService;

    @Override
    @Transactional
    public NoticeBO add(NoticeAddParam param) {

        Notice notice = NoticeConvert.INSTANCE.from(param);
        notice.setDel(DelStatusEnum.NORMAL_VAL);
        notice.setState(NoticeStateEnum.BOOKED.getValue());

        noticeMapper.insert(notice);

        fileService.updateBusId(param.getFiles(), notice.getId());

        return get(notice.getId());
    }

    @Override
    public NoticeBO modify(NoticeModifyParam param) {

        Notice notice = NoticeConvert.INSTANCE.from(param);

        noticeMapper.updateById(notice);

        fileService.updateBusId(param.getFiles(), notice.getId());

        return get(notice.getId());
    }

    @Override
    public void del(DelParam param) {
        noticeMapper.del(param);
    }

    @Override
    public NoticeBO get(String id) {

        Notice notice = noticeMapper.selectById(id);

        return NoticeConvert.INSTANCE.to(notice);
    }

    @Override
    public List<NoticeBO> list(NoticeListParam param) {

        List<Notice> notices =  noticeMapper.list(param);

        return NoticeConvert.INSTANCE.to(notices);
    }

    @Override
    public Page<NoticeBO> page(NoticeQueryParam param) {

        IPage<Notice> page =  noticeMapper.page(param.getPage(), param);

        return NoticeConvert.INSTANCE.to(page);
    }

    @Override
    public Page<NoticeReceiverVBO> pageReceiver(NoticeQueryParam param) {

        IPage<NoticeReceiverV> page =  noticeReceiverVMapper.page(param.getPage(), param);

        return NoticeConvert.INSTANCE.toReceiverV(page);
    }

    @Override
    public NoticeReceiverVBO getReceiverNotice(String id) {

        NoticeReceiverV noticeReceiverV = noticeReceiverVMapper.selectById(id);

        return NoticeConvert.INSTANCE.to(noticeReceiverV);
    }

    /**
     * 发布
     * @param param
     */
    @Override
    @Transactional
    public void release(NoticeReleaseParam param) {

        Notice notice = new Notice();

        notice.setId(param.getId());
        notice.setState(NoticeStateEnum.RELEASE.getValue());
        notice.setReleaseTime(System.currentTimeMillis());
        notice.setReleaseUser(param.getLoginUser().getUserId());
        notice.setReleaseUserName(param.getLoginUser().getName());
        notice.setReleaseDept(param.getLoginUser().getDept());
        notice.setReleaseDeptName(param.getLoginUser().getDeptName());

        noticeMapper.updateById(notice);

        notice = noticeMapper.selectById(param.getId());

        List<NoticeReceiver> receivers = new ArrayList<NoticeReceiver>();

        if(NoticeReceiverTypeEnum.ALL.getValue().intValue() == notice.getType().intValue()){

            List<UserBO> users = userService.listAllEnable();

            for (UserBO user : users){

                DeptBO deptBO = deptService.get(user.getDept());

                NoticeReceiver noticeReceiver = new NoticeReceiver();
                noticeReceiver.setNoticeId(notice.getId());
                noticeReceiver.setState(MsgStateEnum.UN_READ.getValue());
                noticeReceiver.setReceiverTime(System.currentTimeMillis());
                noticeReceiver.setReceiverUser(user.getId());
                noticeReceiver.setReceiverUserName(user.getName());
                noticeReceiver.setReceiverDept(user.getDept());
                noticeReceiver.setReceiverDeptName(deptBO.getName());

                receivers.add(noticeReceiver);
            }

        }else if(NoticeReceiverTypeEnum.DEPT.getValue().intValue() == notice.getType().intValue()){

            JSONArray arr = JSON.parseArray(notice.getRecivers());
            for (int i = 0; i < arr.size(); i++){
                UserListParam listParam = new UserListParam();
                listParam.setLoginUser(param.getLoginUser());
                listParam.setState(StatusEnum.ENABLE.getValue());
                listParam.setDept(arr.getJSONObject(i).getString("id"));
                List<UserBO> users = userService.list(listParam);

                for (UserBO user : users){

                    DeptBO deptBO = deptService.get(user.getDept());

                    NoticeReceiver noticeReceiver = new NoticeReceiver();
                    noticeReceiver.setNoticeId(notice.getId());
                    noticeReceiver.setState(MsgStateEnum.UN_READ.getValue());
                    noticeReceiver.setReceiverTime(System.currentTimeMillis());
                    noticeReceiver.setReceiverUser(user.getId());
                    noticeReceiver.setReceiverUserName(user.getName());
                    noticeReceiver.setReceiverDept(user.getDept());
                    noticeReceiver.setReceiverDeptName(deptBO.getName());

                    receivers.add(noticeReceiver);
                }
            }

        }else if(NoticeReceiverTypeEnum.EMPLOYEE.getValue().intValue() == notice.getType().intValue()){

            JSONArray arr = JSON.parseArray(notice.getRecivers());
            for (int i = 0; i < arr.size(); i++){

                UserBO user = userService.get(arr.getJSONObject(i).getString("id"));
                DeptBO deptBO = deptService.get(user.getDept());

                NoticeReceiver noticeReceiver = new NoticeReceiver();
                noticeReceiver.setNoticeId(notice.getId());
                noticeReceiver.setState(MsgStateEnum.UN_READ.getValue());
                noticeReceiver.setReceiverTime(System.currentTimeMillis());
                noticeReceiver.setReceiverUser(user.getId());
                noticeReceiver.setReceiverUserName(user.getName());
                noticeReceiver.setReceiverDept(user.getDept());
                noticeReceiver.setReceiverDeptName(deptBO.getName());

                receivers.add(noticeReceiver);
            }
        }

        for (NoticeReceiver noticeReceiver : receivers){
            noticeReceiverMapper.insert(noticeReceiver);
        }
    }

    @Transactional
    @Override
    public void unRelease(NoticeReleaseParam param) {

        noticeMapper.unRelease(param.getId());
        noticeReceiverMapper.delByNoticeId(param.getId());

    }

    @Override
    public List<NoticeReceiverBO> listReceiver(String id) {

        List<NoticeReceiver> list = noticeReceiverMapper.listByNoticeId(id);

        return NoticeConvert.INSTANCE.toReceiver(list);
    }

    @Override
    public void read(String id) {

        NoticeReceiver noticeReceiver = new NoticeReceiver();
        noticeReceiver.setId(id);
        noticeReceiver.setReadTime(System.currentTimeMillis());
        noticeReceiver.setState(MsgStateEnum.READ.getValue());

        noticeReceiverMapper.updateById(noticeReceiver);
    }
}
